package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.service.CartInfoAsyncService;
import com.atguigu.gmall.cart.service.CartInfoService;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.item.client.ItemServiceClient;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.baomidou.mybatisplus.extension.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CartInfoServiceImpl implements CartInfoService {
    @Autowired
    private CartInfoAsyncService cartInfoAsyncService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ItemServiceClient itemServiceClient;


    @Override
    public void addCart(Long skuId, Integer skuNum) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String userId = AuthContextHolder.getUserId(request);
        System.out.println(userId);
        if (StringUtils.isEmpty(userId)) {
            userId = AuthContextHolder.getUserTempId(request);
        }
        String redisKey = RedisConst.SECKILL_ORDERS + userId + RedisConst.USER_CART_KEY_SUFFIX;
        String redisHashKey = skuId.toString();
        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(redisKey, redisHashKey);
        if (cartInfo != null) {
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            //默认选中状态
            cartInfo.setIsChecked(CartInfo.ISCHECKEDON);
            cartInfoAsyncService.updata(cartInfo);
        } else {
            cartInfo = new CartInfo();
            SkuInfo skuInfo = itemServiceClient.getSkuInfo(skuId);
            //商品id
            cartInfo.setSkuId(skuId);
            //数量
            cartInfo.setSkuNum(skuNum);
            //图片
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            //价格
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setSkuPrice(skuInfo.getPrice());
            //用户id
            cartInfo.setUserId(userId);
            //描述
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfoAsyncService.inseter(cartInfo);

        }
        System.out.println("线程1" + Thread.currentThread().getName());
        redisTemplate.opsForHash().put(redisKey, redisHashKey, cartInfo);
    }

    @Override
    public CartInfo toCart(Long skuId) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String userId = AuthContextHolder.getUserId(request);
        if (StringUtils.isEmpty(userId)) {
            userId = AuthContextHolder.getUserTempId(request);
        }
        String redisKey = RedisConst.SECKILL_ORDERS + userId + RedisConst.USER_CART_KEY_SUFFIX;
        String redisHashKey = skuId.toString();
        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(redisKey, redisHashKey);
        return cartInfo;
    }


    //整合
    @Override
    public List<CartInfo> cartList(String userId, String userTempId) {
        if(!StringUtils.isEmpty(userId)){
            if(!StringUtils.isEmpty(userTempId)){
                //合并购物车
                List<CartInfo> cartInfo=mergeCartList(userId,userTempId);
                return cartInfo;
            }else {
                //只有真实
                return getRedisCartInfo(userId);

            }
        }else {
            if(!StringUtils.isEmpty(userTempId)){
                //只有虚拟
                return getRedisCartInfo(userTempId);

            }
        }
        return null;
    }

    private List<CartInfo> mergeCartList(String userId, String userTempId) {
        String redisKeyUserId = RedisConst.SECKILL_ORDERS + userId + RedisConst.USER_CART_KEY_SUFFIX;
        String redisKeyUserTemId = RedisConst.SECKILL_ORDERS + userTempId + RedisConst.USER_CART_KEY_SUFFIX;
        List<CartInfo> cartInfoUserId = getRedisCartInfo(userId);
        List<CartInfo> cartInfoUserTempId = getRedisCartInfo(userTempId);
        if(!CollectionUtils.isEmpty(cartInfoUserId)){
            if(!CollectionUtils.isEmpty(cartInfoUserTempId)){
                Map<String, CartInfo> collectUserId = cartInfoUserId.stream().collect(Collectors.toMap(cartInfo->{
                    return cartInfo.getSkuId().toString(); }, cartInfo -> cartInfo));
                cartInfoUserTempId.stream().forEach(cartInfo -> {
                    CartInfo cartInfoSkuId = collectUserId.get(cartInfo.getSkuId().toString());
                    if(cartInfoSkuId!=null){
                        int SkuNum = cartInfo.getSkuNum() + cartInfoSkuId.getSkuNum();
                        cartInfoSkuId.setSkuNum(SkuNum);
                        cartInfoSkuId.setIsChecked(CartInfo.ISCHECKEDON);
                        collectUserId.put(cartInfo.getSkuId().toString(),cartInfoSkuId);
                        cartInfoAsyncService.updataByIdNum(userId,cartInfoSkuId.getSkuId(),SkuNum);
                    }else {
                        cartInfo.setUserId(userId);
                        collectUserId.put(cartInfo.getSkuId().toString(),cartInfo);
                        cartInfoAsyncService.inseter(cartInfo);
                    }
                });
                cartInfoAsyncService.delectUserTemIdCartInfo(userTempId);
                redisTemplate.delete(redisKeyUserTemId);
                redisTemplate.delete(redisKeyUserId);
                redisTemplate.opsForHash().putAll(redisKeyUserId,collectUserId);

                return new ArrayList(collectUserId.values());
            }else {
                return cartInfoUserId;
            }
        }else {
            //只有临时
            if(!CollectionUtils.isEmpty(cartInfoUserTempId)){
                //List<CartInfo> cartListUserTempId
                Map<String, CartInfo> cartInfoMap = cartInfoUserTempId.stream().map(cartInfo -> {
                    //临时用户ID改真实用户ID
                    cartInfo.setUserId(userId);
                    return cartInfo;
                }).collect(
                        Collectors.toMap(cartInfo->{
                            return cartInfo.getSkuId().toString();}, cartInfo -> cartInfo));
                //添加真实用户的缓存
                redisTemplate.opsForHash().putAll(redisKeyUserId,cartInfoMap);
                redisTemplate.delete(redisKeyUserTemId);
                cartInfoAsyncService.updataAsyncCartUserId(userId,userTempId);
                return cartInfoUserTempId;
            }
        }
        return null;
        //1:获取真实用户购物车集合
//        List<CartInfo> cartListUserId = getRedisCartInfo(userId);
//        //2:获取临时用户购物车集合
//        List<CartInfo> cartListUserTempId = getRedisCartInfo(userTempId);
//        //3:判断
//        if(!CollectionUtils.isEmpty(cartListUserId)){
//            //有：真实用户的购物车集合
//            if(!CollectionUtils.isEmpty(cartListUserTempId)){
//                //有：临时用户的购物车集合   合并真+临用户的购物车集合  超难
//
//                // Map  K skuId  V:CartInfo
//                Map<Long, CartInfo> cartInfoMapUserId = cartListUserId.stream().collect(Collectors.
//                        toMap(CartInfo::getSkuId, cartInfo -> cartInfo));
//
//                cartListUserTempId.stream().forEach(cartInfoUserTempId -> {
//                    //1、判断 临时购物车 是否在真实购物车集合中已经存在
//                    CartInfo cartInfoUserId = cartInfoMapUserId.get(cartInfoUserTempId.getSkuId());
//                    if(null != cartInfoUserId){
//                        // 1.1 存在  追加数量 设置选中
//                        cartInfoUserId.setSkuNum(cartInfoUserId.getSkuNum() +
//                                cartInfoUserTempId.getSkuNum());
//                        cartInfoUserId.setIsChecked(1);
//                        //更新Redis
//
//                        String cacheHUserId = RedisConst.SECKILL_ORDERS + userId + RedisConst.USER_CART_KEY_SUFFIX;
//                        redisTemplate.opsForHash().put(cacheHUserId,
//                                cartInfoUserId.getSkuId().toString(),cartInfoUserId);
//                        // 异步更新DB
//                        cartInfoAsyncService.updateByIdAsync(cartInfoUserId);
//                    }else{
//                        // 1.2 不存在 添加新购物车
//                        cartInfoMapUserId.put(cartInfoUserTempId.getSkuId(),cartInfoUserTempId);
//                        //添加Redis
//                        cartInfoUserTempId.setUserId(userId);
//                        String cacheHUserId = RedisConst.SECKILL_ORDERS + userId + RedisConst.USER_CART_KEY_SUFFIX;
//                        redisTemplate.opsForHash().put(cacheHUserId,
//                                cartInfoUserTempId.getSkuId().toString(),cartInfoUserTempId);
//                        //异步添加DB
//                        cartInfoAsyncService.insertAsync(cartInfoUserTempId);
//                    }
//                });
//                //DB中统一删除临时用户的购物车集合
//                cartInfoAsyncService.deleteByUserTempId(userTempId);
//
//                //整体将临时用户的购物车 在redis 删除掉
//                String cacheHUserTempId = RedisConst.SECKILL_ORDERS + userTempId + RedisConst.USER_CART_KEY_SUFFIX;
//                //将临时用户的缓存删除掉
//                redisTemplate.delete(cacheHUserTempId);
//                // cartInfoMapUserId  将Map转回List集合
//                return new ArrayList(cartInfoMapUserId.values());
//            }else{
//                //无：临时用户的购物车集合
//                return cartListUserId;
//            }
//        }else{
//            //无：真实用户的购物车集合
//            if(!CollectionUtils.isEmpty(cartListUserTempId)){
//                //有：临时用户的购物车集合  直接返回临时用户购物车集合
//                //因为真实用户已经存在了 已经登录了 更新缓存（主）   及 更新DB（子线程）（异步）
//                //HashMap   Map map =
//                //          map.remove(k)
//                String cacheHUserTempId = RedisConst.SECKILL_ORDERS + userTempId +
//                        RedisConst.USER_CART_KEY_SUFFIX;
//                String cacheHUserId = RedisConst.SECKILL_ORDERS + userId +
//                        RedisConst.USER_CART_KEY_SUFFIX;
//                //List<CartInfo> cartListUserTempId
//                Map<String, CartInfo> cartInfoMap = cartListUserTempId.stream().map(cartInfo -> {
//                    //临时用户ID改真实用户ID
//                    cartInfo.setUserId(userId);
//                    return cartInfo;
//                }).collect(
//                        Collectors.toMap(cartInfo->{
//                            return cartInfo.getSkuId().toString();}, cartInfo -> cartInfo));
//
//                //添加真实用户的缓存
//                redisTemplate.opsForHash().putAll(cacheHUserId,cartInfoMap);
//                //将临时用户的缓存删除掉
//                redisTemplate.delete(cacheHUserTempId);
//                //开启子线程 更新DB
//                cartInfoAsyncService.updateByIdAsyncExt(userTempId,userId);
//                return cartListUserTempId;
//            }
//        }
//        //啥也没有
//        return null;
    }

    //获取redis中的数据
    private List<CartInfo> getRedisCartInfo(String userId) {
        String redisKey = RedisConst.SECKILL_ORDERS + userId + RedisConst.USER_CART_KEY_SUFFIX;
        List<CartInfo> values = redisTemplate.opsForHash().values(redisKey);
        values.forEach(cartInfo->{
            cartInfo.setSkuPrice(itemServiceClient.getSkuPrice(cartInfo.getSkuId()));
        });
        return values.stream().sorted((o1,o2) -> {
           // o2.getCartTime().compareTo(o1.getCartTime());
            return  o2.getSkuNum()-o1.getSkuNum();
        }).collect(Collectors.toList());
    }

    //更新购物项状态
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //真实用户或临时用户ID
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //获取真实用户ID
        String userId = AuthContextHolder.getUserId(request);
        String redisKey = RedisConst.SECKILL_ORDERS + userId + RedisConst.USER_CART_KEY_SUFFIX;
        String skuIdr = skuId.toString();
        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(redisKey, skuIdr);
        cartInfo.setIsChecked(isChecked);

        redisTemplate.opsForHash().put(redisKey,skuId.toString(),cartInfo);

        cartInfoAsyncService.updata(cartInfo);
    }

    @Override
    public List<CartInfo> getCartListChecked(String userId) {
        String redisKey = RedisConst.SECKILL_ORDERS + userId + RedisConst.USER_CART_KEY_SUFFIX;
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(redisKey);
        return cartInfoList.stream().filter(cartInfo -> {
            return cartInfo.getIsChecked()==1;
        }).collect(Collectors.toList());
    }
}
